﻿Public Class OnlyNumberTextBox
    Inherits TextBox

    Private m_Precision As Integer '输入精度

    Public Sub New()
        MyBase.New()

        '右侧对齐
        Me.TextAlign = HorizontalAlignment.Right

        '关闭输入法
        Me.ImeMode = ImeMode.Close '不关闭还能输入中文

        'm_Precision = 2
    End Sub

    <System.ComponentModel.Browsable(True), System.ComponentModel.Description("设置允许的小数位"), System.ComponentModel.DefaultValue(2)>
    Public Property Precision As Integer
        Get
            Return m_Precision
        End Get
        Set(value As Integer)
            m_Precision = value
        End Set
    End Property

    Protected Overrides Sub OnGotFocus(e As EventArgs)
        MyBase.OnGotFocus(e)

        '关闭中文输入法
        Me.ImeMode = ImeMode.Close
    End Sub

    Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
        MyBase.OnKeyPress(e)

        '如果是空格
        If e.KeyChar = " " Then
            e.Handled = True
            Return
        End If

        '如果是特殊键，不处理
        If Asc(e.KeyChar) <= 32 Or Asc(e.KeyChar） > 126 Then
            Return
        End If


        '如果非数字键，放弃输入
        If (Not Char.IsDigit(e.KeyChar)) And (e.KeyChar <> "-") And (e.KeyChar <> ".") Then
            e.Handled = True
            Return
        End If

        '如果是小数点
        '判断当前是否已经有了小数点
        If e.KeyChar = "." AndAlso Me.Text.IndexOf(".") <> -1 Then
            e.Handled = True
            Return
        End If

        '如果是负号
        If e.KeyChar = "-" AndAlso Me.Text.IndexOf("-") <> -1 Then

            e.Handled = True
            Return
        End If

        If e.KeyChar = "-" Then
            '将当前负号放在数字前面
            Me.SelectionStart = 0
        End If


    End Sub

    Protected Overrides Sub OnTextChanged(e As EventArgs)
        MyBase.OnTextChanged(e)
        '判断当前内容然后截断输入的多余小数位
        Dim tmpS As String = Me.Text
        'Dim tmpN As Decimal
        Dim tmpIndexOfDot As Integer
        Dim tmpDotS As String
        If Not String.IsNullOrEmpty(tmpS) Then
            'tmpN = Decimal.Parse(tmpS)
            tmpIndexOfDot = tmpS.IndexOf(".")
            If tmpIndexOfDot <> -1 Then
                '有小位
                tmpDotS = tmpS.Substring(tmpIndexOfDot + 1)
                If tmpDotS.Length > m_Precision Then
                    '已有足够位数，则截断
                    Me.Text = tmpS.Substring(0, tmpIndexOfDot + m_Precision + 1)
                    Me.SelectionStart = Me.Text.Length
                End If
            End If
        End If

    End Sub


    Protected Overrides Sub WndProc(ByRef m As Message)
        '判断是否是粘贴消息
        If m.Msg = &H302 Then
            'Debug.Print("当前消息：" & m.Msg.ToString)
            m.Result = IntPtr.Zero '拦截
            Return
        End If
        MyBase.WndProc(m)
    End Sub

End Class
